# -*- coding: utf-8 -*-

# 坦克大战游戏

import sys, time, random, math, pygame
from pygame.locals import *
from MyLibrary import *
from datetime import datetime, date, time

reload(sys)
sys.setdefaultencoding('utf-8')

screen_width = 800
screen_height = 600


def angular_velocity(angle):
    vel = Point(0, 0)
    vel.x = math.cos(math.radians(angle))
    vel.y = math.sin(math.radians(angle))
    return vel


class Tank(MySprite):
    def __init__(self, tank_file="tankBase.png", turret_file="tankTurret.png"):
        MySprite.__init__(self)
        self.load(tank_file, 32, 32, 1)
        self.speed = 0.0
        self.scratch = None
        self.float_pos = Point(0, 0)
        self.velocity = Point(0, 0)
        self.turret = MySprite()
        self.turret.load(turret_file, 32, 32, 1)
        self.fire_timer = 0
        self.rotation = 0
        self.move_speed = 1

    def update(self, ticks):
        MySprite.update(self, ticks, 100)
        self.rotation = wrap_angle(self.rotation)
        self.scratch = pygame.transform.rotate(self.image, -self.rotation)
        angle = wrap_angle(self.rotation-90)
        self.velocity = Point(angular_velocity(angle).x * self.move_speed, angular_velocity(angle).y * self.move_speed)
        self.float_pos.x += self.velocity.x
        self.float_pos.y += self.velocity.y

        if self.float_pos.x < 0: self.float_pos.x = screen_width
        elif self.float_pos.x > screen_width: self.float_pos.x = 0
        if self.float_pos.y < 0: self.float_pos.y = screen_height
        elif self.float_pos.y > screen_height: self.float_pos.y = 0

        self.X = int(self.float_pos.x)
        self.Y = int(self.float_pos.y)

        self.turret.position = (self.X, self.Y)
        self.turret.last_frame = 0
        self.turret.update(ticks, 100)
        self.turret.rotation = wrap_angle(self.turret.rotation)
        angle = self.turret.rotation+90
        self.turret.scratch = pygame.transform.rotate(self.turret.image, -angle)

    def draw(self, surface):
        width, height = self.scratch.get_size()
        center = Point(width/2, height/2)
        surface.blit(self.scratch, (self.X-center.x, self.Y-center.y))
        # 炮台
        width, height = self.turret.scratch.get_size()
        center = Point(width/2, height/2)
        surface.blit(self.turret.scratch, (self.turret.X-center.x, self.turret.Y-center.y))

    def __str__(self):
        return MySprite.__str__(self) + "," + str(self.velocity)


class EnemyTank(Tank):
    def __init__(self, tank_file="enemy_tankBase.png", turret_file="enemy_tankTurret.png"):
        Tank.__init__(self, tank_file, turret_file)

    def update(self, ticks):
        self.turret.rotation = wrap_angle(self.rotation-90)
        Tank.update(self, ticks)

    def draw(self, surface):
        Tank.draw(self, surface)


class Bullet():
    def __init__(self, position, img="bullet.png"):
        self.alive = True
        self.color = (250, 20, 20)
        self.position = Point(position.x, position.y)
        self.velocity = Point(0, 0)
        self.rect = Rect(0,0,4,4)
        self.owner = ""
        # self.image = pygame.image.load(img).convert_alpha()

    def update(self, ticks):
        self.position.x += self.velocity.x * 10.0
        self.position.y += self.velocity.y * 10.0
        if self.position.x < 0 or self.position.x > screen_width \
            or self.position.y < 0 or self.position.y > screen_height:
            self.alive = False
        self.rect = Rect(self.position.x, self.position.y, 4, 4)

    def draw(self, surface):
        pos = (int(self.position.x), int(self.position.y))
        pygame.draw.circle(surface, self.color, pos, 4, 0)

    # def draw_img(self, surface):
    #     pos = (int(self.position.x), int(self.position.y))
    #     surface.blit(self.image, pos)


def fire_cannon(tank):
    position = Point(tank.turret.X, tank.turret.Y)
    bullet = Bullet(position)
    angle = tank.turret.rotation
    bullet.velocity = angular_velocity(angle)
    bullets.append(bullet)
    return bullet


def player_fire_cannon():
    bullet = fire_cannon(player)
    bullet.owner = "player"
    bullet.color = (20, 250, 30)

def enemy_fire_cannon():
    bullet = fire_cannon(enemy_tank)
    bullet.owner = "enemy"
    bullet.color = (250, 30, 30)


def game_init():
    global screen, font, timer, backbuffer, player_group, \
    enemy_tank, bullets, crosshair, crosshair_group, player
    global screen_width, screen_height

    screen_width = 800
    screen_height = 600

    pygame.init()
    winstyle = 0  # |FULLSCREEN
    bestdepth = pygame.display.mode_ok((screen_width, screen_height), winstyle, 32)
    screen = pygame.display.set_mode((screen_width, screen_height), winstyle, bestdepth)

    pygame.display.set_caption("坦克大战")
    font = pygame.font.Font("mini.ttf", 20)
    pygame.mouse.set_visible(False)
    timer = pygame.time.Clock()

    # 鼠标
    crosshair = MySprite()
    crosshair.load("crosshair.png")
    crosshair_group = pygame.sprite.GroupSingle()
    crosshair_group.add(crosshair)

    # 玩家
    player = Tank()
    player.float_pos = Point(400, 300)

    # 敌人
    enemy_tank = EnemyTank()
    enemy_tank.float_pos = Point(random.randint(50, 760), 50)
    enemy_tank.rotation = 135

    bullets = list()

    # 背面缓存技术
    backbuffer = pygame.Surface((screen_width, screen_height))


game_init()
game_over = False
player_score = 0
enemy_score = 0
last_time = 0
mouse_x = mouse_y = 0

while True:
    global player
    timer.tick(30)
    ticks = pygame.time.get_ticks()

    # reset
    mouse_up = mouse_down = 0
    mouse_up_x = mouse_up_y = 0
    mouse_down_x = mouse_down_y = 0

    for event in pygame.event.get():
        if event.type == QUIT: sys.exit()
        elif event.type == MOUSEMOTION:
            mouse_x, mouse_y = event.pos
            move_x, move_y = event.rel
        elif event.type == MOUSEBUTTONDOWN:
            mouse_down = event.button
            mouse_down_x, mouse_down_y = event.pos
        elif event.type == MOUSEBUTTONUP:
            mouse_up = event.button
            mouse_up_x, mouse_up_y = event.pos

    keys = pygame.key.get_pressed()
    if keys[K_ESCAPE]: sys.exit()
    elif keys[K_LEFT] or keys[K_a]:
        player.rotation -= 2.0
    elif keys[K_RIGHT] or keys[K_d]:
        player.rotation += 2.0
    elif keys[K_UP] or keys[K_w]:
        player.move_speed = 5.0
    else:
        player.move_speed = 1.0

    if keys[K_SPACE] or mouse_up > 0:
        if ticks > player.fire_timer + 100:
            player.fire_timer = ticks
            player_fire_cannon()

    if not game_over:
        crosshair.position = (mouse_x, mouse_y)
        crosshair_group.update(ticks)

    # 旋转炮台
    angle = target_angle(player.turret.X, player.turret.Y,
                         crosshair.X + crosshair.frame_width/2,
                         crosshair.Y + crosshair.frame_height/2,)
    player.turret.rotation = angle

    # move
    player.update(ticks)

    enemy_tank.update(ticks)

    if ticks > enemy_tank.fire_timer + 1000:
        enemy_tank.fire_timer = ticks
        enemy_fire_cannon()

    # 更新子弹
    for bullet in bullets:
        bullet.update(ticks)
        if bullet.owner == "player":
            if pygame.sprite.collide_rect(bullet, enemy_tank):
                player_score += 1
                bullet.alive = False
        elif bullet.owner == "enemy":
            if pygame.sprite.collide_rect(bullet, player):
                enemy_score += 1
                bullet.alive = False

    # 画屏幕
    # 背景
    bg = pygame.image.load('screen_bg.png').convert()
    backbuffer.blit(bg, (0, 0))

    # backbuffer.fill((100, 100, 20))
    for bullet in bullets:
        bullet.draw(backbuffer)
    enemy_tank.draw(backbuffer)
    player.draw(backbuffer)
    crosshair_group.draw(backbuffer)

    screen.blit(backbuffer, (0, 0))

    if not game_over:
        print_text(font, 0, 0, u"PLAYER " + str(player_score))
        print_text(font, 700, 0, u"ENEMY " + str(enemy_score))
    else:
        print_text(font, 380, 300, u"GAME OVER")

    pygame.display.update()

    for bullet in bullets:
        if bullet.alive == False:
            bullets.remove(bullet)

pygame.quit()



